#!/usr/bin/perl -w
use warnings;
use strict;
use Pod::Usage;
#use Data::Dumper;
#use Storable qw(nstore retrieve);

BEGIN {
    use File::Basename;
    my $path = dirname($0);
    $path = '.' unless defined $path && $path ne '';
    #print STDERR "pushing INC path: [$path]\n";
    push @INC, $path;
}

### user modules
use SimpleError;
use CommandLine;
use InkMap;

### options definition
my %options = (
    'input'          => +{ option => 'input|i=s'             , value =>    undef, check => 1 },
    'output'         => +{ option => 'output|o=s'            , value =>    undef, },
    'information'    => +{ option => 'information|I:s'       , value =>    undef, },
    'overwrite'      => +{ option => 'overwrite|w=s'         , value =>    undef, },
    #--
    #--
    'percentage'     => +{ option => 'percentage|p'          , value =>        0, },
    'FS'             => +{ option => 'field-separator|t=s'   , value =>      ',', },
    #--
    'help'           => +{ option => 'help|h|?'              , value =>    undef, },
    'manual'         => +{ option => 'manual'                , value =>    undef, },
);
use constant OPTION_DEFAULT => '.';
my %option_defaults = (
    'output'         => +{ reference => 'input', value => '*.map2.dat', base => 1, },
    'information'    => +{ reference => 'input', value => '*.info.txt', base => 1, },
    'FS'             => +{ force => 1, value => sub {
                                                my $sep = shift; $sep =~ s/\.s/ /g;
                                                $sep =~ s/\.t/\t/g; return $sep; },  },
);

### command line interface
pod2usage(-exitstatus => 0, -verbose => 1) if @ARGV == 0;
CommandLine::get_options( \%options, 'config' );
pod2usage(-exitstatus => 0, -verbose => 1) if $options{'help'}{'value'};
pod2usage(-exitstatus => 0, -verbose => 2) if $options{'manual'}{'value'};
# --input can be omitted
$options{input}{value} = $options{args}{value}[0]
    if (!defined($options{input}{value}) && defined($options{args}{value})
        && @{$options{args}{value}} == 1);
CommandLine::apply_checks( \%options );
CommandLine::apply_defaults( \%option_defaults,  \%options, OPTION_DEFAULT );
if (defined($options{output}{value}) && -f $options{output}{value}) {
    warning("$options{output}{value}: output file already exists, will be overwritten!");
}
#message( "options with defaults applied:" );
#CommandLine::print_options( \%options );

### main
# ---- timing begin
#my $FS = $options{FS}{value};
my $exec_begin = time();
message("execution begin: ", scalar(localtime($exec_begin)));

# the universal InkMap object
message("creating InkMap object...");
my $ink_map = InkMap::->new(
    Input_File  => $options{input}{value},
);

## information collection and printing
message("collecting map information...");
if (defined($options{information}{value})) {
    my $def_handle; # for storing the current file handle so as to restore it later
    if ($options{information}{value} ne '' && $options{information}{value} ne '-') {
        open INF_OUT, '>', $options{information}{value} or
            error("cannot open file for output: $options{information}{value}: $!");
        message("saving map information to: $options{information}{value}...");
        $def_handle = select INF_OUT;
    }
    $ink_map->collect_info(1); # info collection with printing
    # restore previous file handle
    select $def_handle if defined($def_handle);
} else {
    $ink_map->collect_info(); # info collection without printing
}

## updating pass/fail
if (defined($options{overwrite}{value})) {
    message("reading pass/fail list from: $options{overwrite}{value}...");
    $ink_map->read_pf($options{overwrite}{value});
    message("updating the pass/fail of dies...");
    $ink_map->update_pf();
}

## save new map data to file
if (defined($options{output}{value})) {
    message("saving the new map data to: $options{output}{value}...");
    $ink_map->save_map($options{output}{value});
}

# ---- timing end
my $exec_end = time();
message("execution begin: ", scalar(localtime($exec_begin)));
message("execution   end: ", scalar(localtime($exec_end)));
message("time   consumed: ", ($exec_end - $exec_begin), " second(s)");

### bye
exit 0;

# =============================================================
# S u b r o u t i n e s
# =============================================================

__END__

=head1 NAME

=over 2

inkmap

=back

=head1 SYNOPSIS

Perform operations on the inking map data

=head1 Common Usage Scenarios

=over 2

=back

=head1 OPTIONS

=over 2

=item *

-i, --input=FILE
Specify input.

=item *

-o, --output=FILE
Specify output.

=item *

-t, --separator=STRING
Specify separating string.

=back

=head1 DESCRIPTION

=cut
